/**
 * 获取数据库表列表 (ESM版本)
 * 用于从API获取数据库表列表
 */

import fs from 'fs';
import path from 'path';
import https from 'https';
import http from 'http';
import { fileURLToPath } from 'url';

// 获取当前文件目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 常量定义
const RAW_DATA_DIR = path.resolve(__dirname, '../raw-data');
const TOKEN_FILE = path.join(__dirname, 'token.json');

// 加载配置
const loadConfig = () => {
    try {
        const configPath = path.join(__dirname, 'env.config');
        const content = fs.readFileSync(configPath, 'utf8');
        const config = {};

        content.split('\n').forEach(line => {
            if (line.trim().startsWith('#') || !line.trim()) return;

            const match = line.match(/^([A-Z0-9_]+)="([^"]*)"/);
            if (match) {
                const [, key, value] = match;
                config[key] = value;
            }
        });

        return config;
    } catch (error) {
        console.error('加载配置文件失败:', error);
        process.exit(1);
    }
};

// 获取令牌
const getToken = () => {
    try {
        if (fs.existsSync(TOKEN_FILE)) {
            const tokenData = JSON.parse(fs.readFileSync(TOKEN_FILE, 'utf8'));
            return tokenData.token;
        }

        console.error('令牌文件不存在，请先运行 node scripts/getToken.mjs 获取令牌');
        process.exit(1);
    } catch (error) {
        console.error('读取令牌文件失败:', error.message);
        process.exit(1);
    }
};

// 发送HTTP请求
const sendRequest = (url, method, headers = {}, body = null) => {
    return new Promise((resolve, reject) => {
        const parsedUrl = new URL(url);
        const options = {
            hostname: parsedUrl.hostname,
            port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
            path: parsedUrl.pathname + parsedUrl.search,
            method: method,
            headers: {
                'Content-Type': 'application/json;charset=UTF-8',
                'Accept': 'application/json, text/plain, */*',
                'Cache-Control': 'no-cache',
                ...headers
            }
        };

        console.log(`发送${method}请求到: ${url}`);

        const client = parsedUrl.protocol === 'https:' ? https : http;

        const req = client.request(options, (res) => {
            let data = '';

            res.on('data', (chunk) => {
                data += chunk;
            });

            res.on('end', () => {
                console.log(`状态码: ${res.statusCode}`);

                try {
                    const responseData = data ? JSON.parse(data) : {};
                    if (res.statusCode >= 200 && res.statusCode < 300) {
                        resolve(responseData);
                    } else {
                        console.error('错误响应:', responseData);
                        reject(new Error(`HTTP错误: ${res.statusCode}`));
                    }
                } catch (error) {
                    console.error('解析响应失败:', error.message, '原始数据:', data.substring(0, 200));
                    reject(new Error(`解析响应失败: ${error.message}`));
                }
            });
        });

        req.on('error', (error) => {
            reject(new Error(`请求失败: ${error.message}`));
        });

        if (body) {
            req.write(JSON.stringify(body));
        }

        req.end();
    });
};

// 获取表列表
const getTableList = async (config, token) => {
    try {
        console.log('获取表列表...');

        // 构建请求URL
        const baseUrl = config.AUTO_API_BASE_URL;
        const projectId = config.PROJECT_ID;
        const schema = config.SCHEMA_NAME;

        // 判断要使用的URL格式
        let url;
        let body = null;

        // 默认使用query参数格式
        url = `${baseUrl}/tables?projectId=${encodeURIComponent(projectId)}&schema=${encodeURIComponent(schema)}`;

        console.log('使用URL:', url);

        // 发送请求
        const response = await sendRequest(
            url,
            'GET',
            { 'Authorization': `Bearer ${token}` },
            body
        );

        console.log('成功获取表列表');

        return response;
    } catch (error) {
        console.error('获取表列表失败:', error.message);

        // 尝试使用请求体格式
        try {
            console.log('\n尝试使用请求体格式...');

            const baseUrl = config.AUTO_API_BASE_URL;
            const projectId = config.PROJECT_ID;
            const schema = config.SCHEMA_NAME;

            const url = `${baseUrl}/tables`;
            const body = {
                projectId,
                schema,
                // 添加可能的替代字段名
                id: projectId,
                schemaName: schema
            };

            console.log('使用URL:', url);
            console.log('请求体:', body);

            const response = await sendRequest(
                url,
                'POST',
                { 'Authorization': `Bearer ${token}` },
                body
            );

            console.log('成功获取表列表（请求体格式）');

            return response;
        } catch (retryError) {
            console.error('使用请求体格式重试失败:', retryError.message);
            throw error; // 抛出原始错误
        }
    }
};

// 保存表列表
const saveTableList = (tables) => {
    try {
        if (!fs.existsSync(RAW_DATA_DIR)) {
            fs.mkdirSync(RAW_DATA_DIR, { recursive: true });
        }

        // 保存表列表
        const tablesFile = path.join(RAW_DATA_DIR, 'tables.json');
        fs.writeFileSync(tablesFile, JSON.stringify(tables, null, 2));
        console.log(`表列表已保存到: ${tablesFile}`);

        return true;
    } catch (error) {
        console.error('保存表列表失败:', error.message);
        return false;
    }
};

// 打印表信息
const printTableInfo = (tables) => {
    try {
        if (tables && Array.isArray(tables)) {
            console.log(`\n找到 ${tables.length} 个表:`);

            // 以表格形式打印前10个表
            console.log('┌' + '─'.repeat(40) + '┬' + '─'.repeat(50) + '┐');
            console.log('│ ' + '表名'.padEnd(38) + ' │ ' + '表注释'.padEnd(48) + ' │');
            console.log('├' + '─'.repeat(40) + '┼' + '─'.repeat(50) + '┤');

            const displayCount = Math.min(tables.length, 10);

            for (let i = 0; i < displayCount; i++) {
                const table = tables[i];
                const tableName = table.tableName || table.name || '未知';
                const tableComment = table.tableComment || table.comment || '';

                console.log('│ ' + tableName.padEnd(38).substring(0, 38) + ' │ ' +
                    tableComment.padEnd(48).substring(0, 48) + ' │');
            }

            console.log('└' + '─'.repeat(40) + '┴' + '─'.repeat(50) + '┘');

            if (tables.length > 10) {
                console.log(`... 还有 ${tables.length - 10} 个表未显示`);
            }
        } else {
            console.log('表列表为空或格式不正确');
            console.log('表列表内容:', JSON.stringify(tables, null, 2).substring(0, 300) + '...');
        }
    } catch (error) {
        console.error('打印表信息失败:', error.message);
    }
};

// 处理响应
const processResponse = (response) => {
    // 尝试处理不同的响应格式
    if (response && response.tables && Array.isArray(response.tables)) {
        // 标准格式：{ tables: [...] }
        return response.tables;
    } else if (response && response.data && response.data.tables && Array.isArray(response.data.tables)) {
        // 嵌套格式：{ data: { tables: [...] } }
        return response.data.tables;
    } else if (response && Array.isArray(response)) {
        // 直接数组格式：[...]
        return response;
    } else if (response && typeof response === 'object') {
        // 尝试查找数组属性
        for (const key in response) {
            if (Array.isArray(response[key])) {
                console.log(`使用 ${key} 属性作为表列表`);
                return response[key];
            }
        }
    }

    console.error('无法解析响应格式:', JSON.stringify(response, null, 2).substring(0, 300) + '...');
    return null;
};

// 主函数
const main = async () => {
    console.log('=== 获取数据库表列表开始 ===');

    try {
        const config = loadConfig();
        const token = getToken();

        console.log(`API基础URL: ${config.AUTO_API_BASE_URL}`);
        console.log(`项目ID: ${config.PROJECT_ID}`);
        console.log(`Schema: ${config.SCHEMA_NAME}`);

        // 获取表列表
        const response = await getTableList(config, token);

        // 处理响应
        const tables = processResponse(response);

        if (tables) {
            // 打印表信息
            printTableInfo(tables);

            // 保存表列表
            saveTableList(tables);

            console.log('\n表列表获取和保存成功');
        } else {
            console.error('表列表获取失败：无法解析响应');
            process.exit(1);
        }
    } catch (error) {
        console.error('获取表列表失败:', error.message);
        process.exit(1);
    }

    console.log('\n=== 获取数据库表列表完成 ===');
};

// 执行主函数
main().catch(error => {
    console.error('执行过程中发生错误:', error);
    process.exit(1);
}); 